/**
 * 生成树型
 * @param data
 * @param idField
 * @param pidField
 * @param pid
 * @param childName
 * @returns {[]}
 */
export function makeTree(data: any[], idField = 'id', pidField = 'pid', pid: any = '', childName = 'children') {
	const idMapping = data.reduce((acc, el, i) => {
		acc[el[idField]] = i;
		return acc;
	}, {});
	const result: any[] = [];
	data.forEach(el => {
		// 判断根节点
		if (el[pidField] === pid) {
			result.push(el);
			return;
		}
		// 用映射表找到父元素
		const parentEl = data[idMapping[el[pidField]]];
		if (!parentEl) {
			result.push(el);
			return;
		}
		// 把当前元素添加到父元素的`children`数组中
		parentEl[childName] = [...(parentEl[childName] || []), el];
	});
	return result;
}

/**
 * 数组指定下标值转为下标
 * @param arr
 * @param key
 * @returns {{}}
 */
export function arrayValueToKey(arr: any, key: string) {
	let objReturn: any = {};
	arr.forEach(function (v: any) {
		objReturn[v[key]] = v;
	});
	return objReturn;
}

/**
 * 格式化枚举数据
 * @param data
 */
export function formatEnumData(data: any) {
	const result: any = {};
	for (let k in data) {
		result[k] = {};
		for (let k2 in data[k]) {
			result[k][k2] = {};
			for (let k3 in data[k][k2]) {
				const tmp = data[k][k2][k3];
				result[k][k2][tmp.value] = tmp.label;
			}
		}
	}
	return result;
}

/**
 * 数组分组
 * @param arr
 * @param gby
 * @returns {{}}
 * @constructor
 */
export function arrayGroupBy(arr: any, gby: any) {
	/**
	 * 处理分组
	 * @param noteObj
	 * @param rule
	 * @param gby
	 * @param gIndex
	 * @param maxIndex
	 */
	let setGroupObj = function (noteObj: any, rule: any, gby: any, gIndex: any, maxIndex: any) {
		let groupName = rule[gby[gIndex]];
		if (gIndex === maxIndex) {
			if (noteObj[groupName] === undefined)
				noteObj[groupName] = [];
			if (noteObj[groupName].indexOf(rule) < 0) {
				noteObj[groupName].push(rule);
			}
		} else {
			if (noteObj[groupName] === undefined) {
				noteObj[groupName] = {};
			}
			setGroupObj(noteObj[groupName], rule, gby, gIndex + 1, maxIndex);
		}
	}
	let noteObj = {};
	for (let i = 0; i < arr.length; i++) {
		setGroupObj(noteObj, arr[i], gby, 0, gby.length - 1);
	}
	return noteObj;
}

/**
 * 格式化时间戳
 * dateFormat(11111111111111, 'Y年m月d日 H时i分')
 * → "2322年02月06日 03时45分"
 * @param timestamp
 * @param formats
 * @returns {string}
 */
export function dateFormat(timestamp: number, formats?: string) {
	if (!timestamp || timestamp.toString().length <= 5) {
		return '';
	}
	timestamp = timestamp * 1000;
	// formats格式包括
	// 1. Y-m-d
	// 2. Y-m-d H:i:s
	// 3. Y年m月d日
	// 4. Y年m月d日 H时i分
	formats = formats || 'Y-m-d H:i:s';
	const zero = function (value: any) {
		if (value < 10) {
			return '0' + value;
		}
		return value;
	};
	const myDate = timestamp ? new Date(timestamp) : new Date();
	const year = myDate.getFullYear();
	const month = zero(myDate.getMonth() + 1);
	const day = zero(myDate.getDate());
	const hour = zero(myDate.getHours());
	const minute = zero(myDate.getMinutes());
	const second = zero(myDate.getSeconds());
	return formats.replace(/[YmdHis]/ig, function (matches) {
		const obj = {
			Y: year,
			m: month,
			d: day,
			H: hour,
			i: minute,
			s: second
		};
		return (obj as any)[matches];
	});
}


/**
 * 删除对象的控制
 * @param objData
 * @param parent
 * @param parentKey
 */
export function delObjEmptyVal(objData: any, parent: any = {}, parentKey: string = '') {
	for (let i in objData) {
		if (objData[i] === '' || objData[i] === undefined || JSON.stringify(objData[i]) === '{}' || JSON.stringify(objData[i]) === '[]') {
			delete objData[i];
			if (JSON.stringify(objData) === '{}' || JSON.stringify(objData) === '[]') {
				delete parent[parentKey];
			}
		}
		if (typeof (objData[i]) === 'object') {
			delObjEmptyVal(objData[i], objData, i);
		}
	}
}

/**
 * 获取是否手机
 */
export function getIsMobile() {
	const {width} = useWindowSize();
	const MOBILE_BREAKPOINT = 500;
	return computed(() => width.value < MOBILE_BREAKPOINT);
}

/**
 * 列表转标签值选项
 * @param data
 * @param labelKey
 * @param valueKey
 * @param retainFields
 */
export function listToLabelValueOptions(data: any, labelKey: string, valueKey: string, retainFields?: any) {
	const result: any = [];
	data.forEach((item: any) => {
		const temp: any = {label: item[labelKey], value: item[valueKey]};
		if (retainFields) {
			retainFields.forEach((retainKey: any) => {
				temp[retainKey] = item[retainKey];
			})
		}
		result.push(temp);
	});
	return result;
}

/**
 * 禁止输入空格
 * @param val 当前值字符串
 * @returns 返回处理后的字符串
 */
export function verifyAndSpace(val: string) {
	// 匹配空格
	// 返回结果
	return val.replace(/(^\s*)|(\s*$)/g, '');
}

/**
 * 手机号码
 * @param val 当前值字符串
 * @returns 返回 true: 手机号码正确
 */
export function verifyMobile(val: string) {
	// false: 手机号码不正确
	return /^1[3456789][0-9]{9}$/.test(val);
}

/**
 * 国内电话号码
 * @param val 当前值字符串
 * @returns 返回 true: 国内电话号码正确
 */
export function verifyTelPhone(val: string) {
	// false: 国内电话号码不正确
	return /\d{3}-\d{8}|\d{4}-\d{7}/.test(val);
}

/**
 * 登录账号 (字母开头，允许5-16字节，允许字母数字下划线)
 * @param val 当前值字符串
 * @returns 返回 true: 登录账号正确
 */
export function verifyAccount(val: string) {
	// false: 登录账号不正确
	return /^[a-zA-Z][a-zA-Z0-9_]{4,15}$/.test(val);
}

/**
 * 密码 (以字母开头，长度在6~16之间，只能包含字母、数字和下划线)
 * @param val 当前值字符串
 * @returns 返回 true: 密码正确
 */
export function verifyPassword(val: string) {
	// false: 密码不正确
	return /^[a-zA-Z]\w{5,15}$/.test(val);
}

/**
 * 强密码 (字母+数字+特殊字符，长度在6-16之间)
 * @param val 当前值字符串
 * @returns 返回 true: 强密码正确
 */
export function verifyPasswordPowerful(val: string) {
	// false: 强密码不正确
	return /^(?![a-zA-Z]+$)(?!\d+$)(?![!@#$%^&\.*]+$)(?![a-zA-Z\d]+$)(?![a-zA-Z!@#$%^&\.*]+$)(?![\d!@#$%^&\.*]+$)[a-zA-Z\d!@#$%^&\.*]{6,16}$/.test(val);
}

/**
 * 密码强度
 * @param val 当前值字符串
 * @description 弱：纯数字，纯字母，纯特殊字符
 * @description 中：字母+数字，字母+特殊字符，数字+特殊字符
 * @description 强：字母+数字+特殊字符
 * @returns 返回处理后的字符串：弱、中、强
 */
export function verifyPasswordStrength(val: string) {
	let v = '';
	// 弱：纯数字，纯字母，纯特殊字符
	if (/^(?:\d+|[a-zA-Z]+|[!@#$%^&\.*]+){6,16}$/.test(val)) v = '弱';
	// 中：字母+数字，字母+特殊字符，数字+特殊字符
	if (/^(?![a-zA-z]+$)(?!\d+$)(?![!@#$%^&\.*]+$)[a-zA-Z\d!@#$%^&\.*]{6,16}$/.test(val)) v = '中';
	// 强：字母+数字+特殊字符
	if (/^(?![a-zA-z]+$)(?!\d+$)(?![!@#$%^&\.*]+$)(?![a-zA-z\d]+$)(?![a-zA-z!@#$%^&\.*]+$)(?![\d!@#$%^&\.*]+$)[a-zA-Z\d!@#$%^&\.*]{6,16}$/.test(val)) v = '强';
	// 返回结果
	return v;
}

/**
 * IP地址
 * @param val 当前值字符串
 * @returns 返回 true: IP地址正确
 */
export function verifyIPAddress(val: string) {
	// false: IP地址不正确
	return /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/.test(val);
}

/**
 * 邮箱
 * @param val 当前值字符串
 * @returns 返回 true: 邮箱正确
 */
export function verifyEmail(val: string) {
	// false: 邮箱不正确
	return /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(val);
}